


#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winapi/shlwapi.h>



#include "../xxbot/librarys/xCore/xCore.h"
#include "../xxbot/librarys/xFile/xFile.h"



#define _STDBOOL_H
#include "sciter/sciter-x.h"



#pragma comment (lib, "shell32")
#pragma comment (lib, "user32")
#pragma comment (lib, "kernel32")
#pragma comment (lib, "shlwapi")



ISciterAPI* Sciter;



ISciterAPI* (*SciterAPI)();
HANDLE hDllSciter = NULL;



wstr sAppFileW = NULL;
wstr sAppPathW = NULL;
wstr sLibFileW = NULL;
wstr sLibPathW = NULL;
wstr sBinFileW = NULL;
wstr sBinPathW = NULL;
uint32 iAppFileSize, iAppPathSize, iLibFileSize, iLibPathSize, iBinFileSize, iBinPathSize;



#include "sciter/CallRouter/CallRouter.h"
#include "sciter/CallRouter/RegRtlib.h"





// JS 运行库补充（占坑避免出错）
BOOL Rtl_JS_SetRetVal(SCRIPTING_METHOD_PARAMS* params) {
	return TRUE;
}



// 创建界面
static BOOL SC_CALLBACK element_proc(LPVOID tag, HELEMENT he, UINT evtg, SCRIPTING_METHOD_PARAMS* params)
{
	if (evtg == HANDLE_SCRIPTING_METHOD_CALL)
	{
		return CallRouterProc(params);
	}
	return false;
}



// handle SC_LOAD_DATA requests - get data from resources of this application
UINT DoLoadData(LPSCN_LOAD_DATA pnmld)
{
  //LPCBYTE pb = 0; UINT cb = 0;
  //wchar_t* wu = pnmld->uri;
  /*
  else if(wu.like(WSTR("res:*")))
  {
    // then by calling possibly overloaded load_resource_data method
    if(sciter::load_resource_data(ghInstance,wu.start+4, pb, cb))
      ::SciterDataReady( pnmld->hwnd, pnmld->uri, pb,  cb);
  }*/
  /* else if(wu.like(WSTR("this://app/*"))) {
    // try to get them from archive (if any, you need to call sciter::archive::open() first)
    aux::bytes adata = sciter::archive::instance().get(wu.start+11);
    if(adata.length)
      ::SciterDataReady( pnmld->hwnd, pnmld->uri, adata.start, adata.length);
  }*/
  return LOAD_OK;
}

// fulfill SC_ATTACH_BEHAVIOR request 
/*
UINT DoAttachBehavior( LPSCN_ATTACH_BEHAVIOR lpab )
{
  sciter::event_handler *pb = sciter::behavior_factory::create(lpab->behaviorName, lpab->element);
  if(pb)
  {
    lpab->elementTag  = pb;
    lpab->elementProc = sciter::event_handler::element_proc;
    return TRUE;
  }
  return FALSE;
}*/

UINT SC_CALLBACK SciterCallback( LPSCITER_CALLBACK_NOTIFICATION pns, LPVOID callbackParam )
{
  // here are all notifiactions
  switch(pns->code) 
  {
    case SC_LOAD_DATA:          return DoLoadData((LPSCN_LOAD_DATA) pns);
    //case SC_ATTACH_BEHAVIOR:    return DoAttachBehavior((LPSCN_ATTACH_BEHAVIOR)pns );
  }
  return 0;
}



// sciter 封装
int Sciter_LoadGUI(wstr sPathDll, wstr sFile, int w, int h)
{
	if ( xFile_ExistsW(sFile) == FALSE ) {
		MessageBox(0, "Cannot find html file !", "Error", MB_OK | MB_ICONERROR);
		return  FALSE;
	}
	
	// 加载 DLL
	if ( SciterAPI == NULL ) {
		hDllSciter = LoadLibraryW(sPathDll);
		SciterAPI = (ptr)GetProcAddress(hDllSciter, "SciterAPI");
	}
	if ( SciterAPI == NULL ) {
		MessageBox(0, "Sciter Dll LoadLibrary failed !", "Error", MB_OK | MB_ICONERROR);
		return  FALSE;
	}

	// 加载 Sciter
	Sciter = SciterAPI();
	if (Sciter == NULL) {
		MessageBox(0, "Sciter Initialization failed !", "Error", MB_OK | MB_ICONERROR);
		return  FALSE;
	}
	
	// 初始化 OLE
	OleInitialize(NULL);
	
	// 获取路径
	if ( sAppFileW ) { xCore_free(sAppFileW); }
	if ( sAppPathW ) { xCore_free(sAppPathW); }
	if ( sLibFileW ) { xCore_free(sLibFileW); }
	if ( sLibPathW ) { xCore_free(sLibPathW); }
	if ( sBinFileW ) { xCore_free(sBinFileW); }
	if ( sBinPathW ) { xCore_free(sBinPathW); }
	sAppFileW = Path_GetAbsW(sFile, NULL);
	sAppPathW = Path_FilePathW(sAppFileW);
	sLibFileW = Path_GetAbsW(sPathDll, NULL);
	sLibPathW = Path_FilePathW(sLibFileW);
	sBinFileW = xCore_ModFileW(NULL);
	sBinPathW = xCore_ModPathW(NULL);
	iAppFileSize = wcslen(sAppFileW);
	iAppPathSize = wcslen(sAppPathW);
	iLibFileSize = wcslen(sLibFileW);
	iLibPathSize = wcslen(sLibPathW);
	iBinFileSize = wcslen(sBinFileW);
	iBinPathSize = wcslen(sBinPathW);
	
	// 初始化全局数据
	InitCallRouter();
	RegRtlibFuncs();
	RegFunc("SetRetVal", Rtl_JS_SetRetVal);

	// 启用被 Sciter 默认禁止的函数库
	Sciter->SciterSetOption(NULL, SCITER_SET_SCRIPT_RUNTIME_FEATURES, ALLOW_FILE_IO | ALLOW_SOCKET_IO | ALLOW_EVAL | ALLOW_SYSINFO);
	
	// 启用调试模式
	Sciter->SciterSetOption(NULL, SCITER_SET_DEBUG_MODE, TRUE);

	// 启动 Sciter 窗口
	int cw = GetSystemMetrics(SM_CXSCREEN);
	int ch = GetSystemMetrics(SM_CYSCREEN);
    RECT rect = { (cw - w) / 2, (ch - h) / 2, ((cw - w) / 2) + w, ((ch - h) / 2) + h };
	xCore.AppWindow = Sciter->SciterCreateWindow(SW_TITLEBAR | SW_RESIZEABLE | SW_CONTROLS | SW_MAIN | SW_ENABLE_DEBUG, &rect, NULL, 0, NULL);
	if ( xCore.AppWindow == NULL) {
		MessageBox(0, "Sciter Create Window failed !", "Error", MB_OK | MB_ICONERROR);
		return  FALSE;
	}
	
	//Sciter->SciterSetCallback(xCore.AppWindow, &SciterCallback, NULL);
	
	// 添加回调函数
	Sciter->SciterWindowAttachEventHandler(xCore.AppWindow, (ptr)&element_proc, NULL, HANDLE_SCRIPTING_METHOD_CALL);
	
	// 加载默认界面 [从文件]
	Sciter->SciterLoadFile(xCore.AppWindow, sFile);
	ShowWindow(xCore.AppWindow, SW_SHOWNORMAL);
	SetForegroundWindow(xCore.AppWindow);
	
	// 处理消息循环
	MSG msg;
	while( GetMessage(&msg, NULL, 0, 0) ) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	
	// 释放全局数据
	UnitCallRouter();
	
	return TRUE;
}



int main(int argc, astr* argv)
{
	xCoreInit();
	wstr sAppPath = xCore_AppPathW();
	wstr sIniFile = Path_JoinW(sAppPath, L"app.ini");
	#if defined(__x86_64__) || defined(_WIN64)
		wstr sVal = Ini_ReadW(sIniFile, L"xbox", L"sciter64");
	#else
		wstr sVal = Ini_ReadW(sIniFile, L"xbox", L"sciter32");
	#endif
	wstr sPathDLL = xCore_ReplaceW(sVal, L"{$AppPath}", sAppPath);
	xCore_free(sVal);
	sVal = Ini_ReadW(sIniFile, L"xbox", L"index");
	wstr sPathGUI = xCore_ReplaceW(sVal, L"{$AppPath}", sAppPath);
	xCore_free(sVal);
	int w = Ini_ReadIntW(sIniFile, L"xbox", L"w");
	int h = Ini_ReadIntW(sIniFile, L"xbox", L"h");
	int bDebug = Ini_ReadIntW(sIniFile, L"xbox", L"debug");
	if ( bDebug ) { MessageBoxW(0, sPathDLL, sPathGUI, 0); }
	xCore_free(sAppPath);
	xCore_free(sIniFile);
	Sciter_LoadGUI(sPathDLL, sPathGUI, w, h);
	xCore_free(sPathDLL);
	xCore_free(sPathGUI);
	return 0;
}


